class RunLengthEncoding {

    String encode(final String inputEncodeString) {
        StringBuilder results = new StringBuilder();
        if (inputEncodeString.length() == 0) {
            return results.toString();
        }
        char[] charEncodeArray = inputEncodeString.toCharArray();

        char currentIndex = 0;
        char[] charArray = new char[charEncodeArray.length];
        int[] countArray = new int[charEncodeArray.length];

//        initial Array
        charArray[currentIndex] = charEncodeArray[currentIndex];
        countArray[currentIndex] = 1;

//        important start index is 1
        for (int i = 1; i < charEncodeArray.length; i++) {
            if (charArray[currentIndex] == charEncodeArray[i]) {
                countArray[currentIndex]++;
            } else {
                currentIndex++;
                charArray[currentIndex] = charEncodeArray[i];
                countArray[currentIndex] = 1;
            }
        }

        for (int i = 0; i < countArray.length; i++) {
            if (countArray[i] == 0) {
                break;
            }

            results.append(String.format("%s%s",
                    countArray[i] == 1 ? "" : countArray[i],
                    charArray[i]));
        }

        return results.toString();
    }

    String decode(final String inputDecodeString) {

        StringBuilder results = new StringBuilder();
        if (inputDecodeString.length() == 0) {
            return results.toString();
        }
        char[] charDecodeArray = inputDecodeString.toCharArray();

        int count = 0;
        for (char aChar : charDecodeArray)
            if ((aChar >= '0') && (aChar <= '9')) {
                count = count * 10 + Character.getNumericValue(aChar);
            } else {
                if (count == 0) {
                    results.append(aChar);
                } else {
//                    for (int j = 0; j < count; j++) results.append(aChar);
//                    is same with above
                    java.util.stream.IntStream
                            .range(0, count)
                            .map(j -> aChar)
                            .forEach((ch) -> results.append((char) ch));
                }
                count = 0;
            }

        return results.toString();
    }
}